use crate::models::{PriceHistoryPoint, StockPrice};
use chrono::{Duration, Utc};
use rand::{rngs::StdRng, Rng, SeedableRng};
use std::collections::HashMap;
use std::sync::{Arc, Mutex};

#[derive(Clone)]
pub struct PriceService {
    rng: Arc<Mutex<StdRng>>,
    // 简单内存历史（仅示例），生产环境请使用时序库或DB
    history: Arc<Mutex<HashMap<String, Vec<PriceHistoryPoint>>>>,
}

impl PriceService {
    pub fn new() -> Self {
        Self {
            rng: Arc::new(Mutex::new(StdRng::from_entropy())),
            history: Arc::new(Mutex::new(HashMap::new())),
        }
    }

    pub fn new_with_seed(seed: u64) -> Self {
        Self {
            rng: Arc::new(Mutex::new(StdRng::seed_from_u64(seed))),
            history: Arc::new(Mutex::new(HashMap::new())),
        }
    }

    pub fn tick(&self, symbol: &str) -> StockPrice {
        // 随机游走模拟价差
        let mut rng = self.rng.lock().unwrap();
        let base: f64 = 100.0;
        let drift: f64 = rng.gen_range(-1.5_f64..1.5_f64);
        let price = (base + drift).max(0.1f64);

        let point = PriceHistoryPoint {
            ts: Utc::now(),
            price,
        };

        {
            let mut h = self.history.lock().unwrap();
            let entry = h.entry(symbol.to_string()).or_default();
            entry.push(point.clone());
            // 限制历史长度，避免内存增长
            if entry.len() > 1024 {
                let keep = entry.split_off(entry.len() - 512);
                *entry = keep;
            }
        }

        StockPrice {
            symbol: symbol.to_string(),
            price,
            ts: Utc::now(),
        }
    }

    pub fn history(&self, symbol: &str, minutes: i64) -> Vec<PriceHistoryPoint> {
        let cutoff = Utc::now() - Duration::minutes(minutes);
        let h = self.history.lock().unwrap();
        h.get(symbol)
            .cloned()
            .unwrap_or_default()
            .into_iter()
            .filter(|p| p.ts >= cutoff)
            .collect()
    }
}